package cn.broadsense.web.controller;

import cn.broadsense.common.annotation.Anonymous;
import cn.broadsense.common.annotation.RepeatSubmit;
import cn.broadsense.common.constant.CacheConstants;
import cn.broadsense.common.constant.Constants;
import cn.broadsense.common.core.domain.R;
import cn.broadsense.common.core.domain.entity.SysUser;
import cn.broadsense.common.core.domain.model.LoginUser;
import cn.broadsense.common.core.redis.RedisCache;
import cn.broadsense.common.interfaces.ValidationGroup;
import cn.broadsense.common.utils.SecurityUtils;
import cn.broadsense.common.utils.SmsUtils;
import cn.broadsense.common.utils.StringUtils;
import cn.broadsense.framework.manager.AsyncManager;
import cn.broadsense.framework.manager.factory.AsyncFactory;
import cn.broadsense.framework.web.service.SysLoginService;
import cn.broadsense.framework.web.service.TokenService;
import cn.broadsense.system.service.ISysUserService;
import cn.broadsense.web.controller.body.AppLoginBody;
import cn.broadsense.web.controller.body.SmsBody;
import cn.broadsense.web.controller.vo.LoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/v1/auth")
@Api(tags = "认证模块")
public class AuthController {

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysUserService sysUserService;


    /**
     * 登录
     *
     * @param body
     * @return
     */
    @ApiOperation("账号密码登录")
    @PostMapping("/login")
    @Anonymous
    public R<LoginVO> login(@RequestBody @Valid AppLoginBody body) {
        String token = loginService.login(body.getUserName(), body.getPassword());
        return R.ok(new LoginVO(token));
    }

    @ApiOperation("获取短信验证码")
    @PostMapping("/sms")
    @Anonymous
    @RepeatSubmit(interval = 60000, message = "获取验证码过于频繁")
    public R getSms(@RequestBody @Validated(ValidationGroup.Query.class) SmsBody body) {
        // 获取手机号码
        String phonenumber = body.getPhonenumber();
        // 生成验证码
        String captcha = SmsUtils.generateCaptcha(6);
        // TODO 发送验证码
        // 存储到缓存
        log.info("[获取验证码] 手机号：{},验证码：{}", phonenumber, captcha);
        String key = CacheConstants.SMS_CAPTCHA_CODE_KEY + phonenumber;
        redisCache.setCacheObject(key, captcha);
        return R.ok();
    }

    @ApiOperation("短信登录")
    @PostMapping("/sms/login")
    @Anonymous
    public R smsLogin(@RequestBody @Validated(ValidationGroup.Insert.class) SmsBody body) {
        String token = loginService.smsLogin(body.getPhonenumber(), body.getCaptcha());
        return R.ok(new LoginVO(token));
    }

    /**
     * 退出登录
     *
     * @return
     */
    @ApiOperation("退出登录")
    @PostMapping("/logout")
    @Anonymous
    public R logout() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser)) {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
        }
        return R.ok();
    }
}
